#pragma once
#include <Windows.h>
#include <string>
#include <vector>
#include "Color.h"


//+==================================================================+
#define	SOUND_NONE			(0)
#define	SOUND_NORMAL		(1)
#define	SOUND_WHISTLE		(1<<1)
#define	SOUND_CLAP			(1<<2)
#define	SOUND_FINISH		(1<<3)

//+==================================================================+
#define	CIRCLE				(1<<0)
#define	SLIDER				(1<<1)
#define	NEW_COMBO			(1<<2)
#define	SPINNER				(1<<3)

//+==================================================================+
struct HitObject
{
	int	x,										// = [0,512] = x-coordinate (for sliders: the first point), might be negative or greater than 512 -> outside the screen(?)
			y,										// = [0,384] = y-coordinate (for sliders: the first point), might be negative or greater than 384 -> outside the screen(?)
			time,									// start time of the (first for sliders) point
			type,									// = (1=circle, 2=slider, 8=spinner)| 4=new_combo
			sound,								// = (0=none | 1=normal | 2=whistle | 4=drum | 8=finish)
			stop;									// for spinners: stop time; for sliders: length in pixels = 100 * SliderMultiplier * duration in beats
//----
	std::vector<POINT> points;				// only for sliders: points, defining the curve
	int		count;							// if 2 -> return at the end, etc.
	wchar_t	interpolationType;			// 'L' = linear, 'B' = bezier, 'C' = catmull-rom
};

//+==================================================================+
struct TimingPoint
{
	int		time;
	double	msPerBeat;						// = 60000 / bpm
	int		meter,							// = {3=3/4, 4=4/4}
				sampleSet,						// = {1=normal, 2=soft}
				customOverride,				// = {0=no, 1=set1, 2=set2}
				volume,							// = [0,100]
				unknown,							// = {0,1}
				kiaiMode;						// = {0,1}
};

//+==================================================================+
struct BreakPeriod
{
	int	start,
			stop;
};



//+==================================================================+
struct OsuFile
{
//+------------------------------------------------------------------+
	struct Metadata
	{
		std::wstring				title,
										artist,
										creator,
										version,
										source,
										tags;
	};

//+------------------------------------------------------------------+
	Metadata							metadata;

	int								audioLeadIn,
										videoStartTime,
										previewTime,
										countdown,
										overallDifficulty;
	double							sliderMultiplier;

	std::wstring					audioFilename,
										videoFilename,
										backgroundFilename;

	std::vector<BreakPeriod>	breakPeriods;
	std::vector<Color>			comboColors;
	std::vector<HitObject>		hitObjects;
	std::vector<TimingPoint>	timingPoints;

//+------------------------------------------------------------------+
	OsuFile(LPCWSTR filename)				{	readOsuFile(filename);	}
	OsuFile()									{	reset();						}
	~OsuFile()									{									}

//+------------------------------------------------------------------+
	void readOsuFile(LPCWSTR filename);
	void reset();

//+------------------------------------------------------------------+
// For sorting by difficulty
	bool operator < (const OsuFile &b) const
	{
		if(overallDifficulty != b.overallDifficulty)
			return overallDifficulty < b.overallDifficulty;

		return metadata.title < b.metadata.title;
	}

};

